package com.woniuxy.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.entity.AllRun;
import com.woniuxy.entity.DTO.GrabEvent;
import com.woniuxy.entity.DTO.RunPostMessageDTO;
import com.woniuxy.mapper.RunMapper;
import com.woniuxy.service.RunService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
public class RunServiceImpl extends ServiceImpl<RunMapper, AllRun> implements RunService {
    @Autowired
    private RunMapper runMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public List<RunPostMessageDTO> getListRun(int number) {
        List<RunPostMessageDTO> list = runMapper.getListRun(number);
        return list;
    }

    @Override
    public Boolean acceptRun(String runNumber, Integer userId) {
        //用Redis实现抢单操作
        String stockKey = "stock:" + runNumber;
        String userKey = "accepted_users:" + runNumber +":"+ userId;
        //lua脚本
        String luaScript = "local stock_key = KEYS[1]\n" +
                "local user_key = KEYS[2]\n" +
                "local stock = tonumber(redis.call('get',stock_key))\n" +
                "if stock == nil or stock <= 0 then \n" +
                "return -1\n" +
                "end\n" +
                "if redis.call('sismember',user_key,ARGV[1]) == 1 then\n" +
                "return 0\n" +
                "end\n" +
                "redis.call('decr',stock_key)\n" +
                "redis.call('sadd',user_key,ARGV[1])\n" +
                "return 1";
        RedisScript<Long> script = RedisScript.of(luaScript, Long.class);
        Object result = redisTemplate.execute(
                script,
                Arrays.asList(stockKey, userKey),
                userId.toString()
        );
        if (result.toString().equals("1")){
            return true;
        }
        return false;
    }

    // 生产者
    public void sendGrabEvent(GrabEvent grabEvent) {
        rabbitTemplate.convertAndSend(
                "directExchange",
                "a",
                grabEvent,
                message -> {
                    // 设置消息ID用于幂等
                    message.getMessageProperties()
                            .setMessageId(UUID.randomUUID().toString());
                    return message;
                }
        );
    }
}
